﻿/*********************************************
Copyright (c) 2013 All Right Reserved, bixaps

This source is subject to the Microsoft Permissive License.
All other rights reserved.      

THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Author: Raj Bandi
Email: raj.bandi@hotmail.com
Website: www.rajbandi.net
*********************************************/

/*********************************************
Common namespaces & functions
*********************************************/
(function () {
    "use strict";

    WinJS.Namespace.define("Bixaps.Util",
        {
            Icons: {
                ARROW_HEAD_RIGHT: ''
               , ARROW_HEAD_DOWN: ''
               , ARROW_HEAD_LEFT: ''
               , ARROW_HEAD_UP: ''
            },
            Keys: {
                BACKSPACE: 8,
                COMMA: 188,
                DELETE: 46,
                DOWN: 40,
                END: 35,
                ENTER: 13,
                ESCAPE: 27,
                HOME: 36,
                LEFT: 37,
                NUMPAD_ADD: 107,
                NUMPAD_DECIMAL: 110,
                NUMPAD_DIVIDE: 111,
                NUMPAD_ENTER: 108,
                NUMPAD_MULTIPLY: 106,
                NUMPAD_SUBTRACT: 109,
                PAGE_DOWN: 34,
                PAGE_UP: 33,
                PERIOD: 190,
                RIGHT: 39,
                SPACE: 32,
                TAB: 9,
                UP: 38
            },
            IsNull: function (el) {
                return el == null || el == 'undefined';
            },
            IsNullOrEmpty: function (el) {
                return el == null || el == 'undefined' || el == '';
            },
            getListItemHeight: function (el) {
                var h = 0;
                if (!Bixaps.Util.IsNull(el)) {
                    var node = null;
                    for (var i = 0; i < el.childNodes.length; i++) {
                        node = el.childNodes[i];
                        if (node.innerHTML.length > 5) {
                            h += el.childNodes[i].offsetHeight;
                        }
                    }
                }
                return h;
            }
        });

})();


(function () {
    "use strict";

    var listView = WinJS.UI.ListView;

    //define the events required
    listView.onItemsLoading = "onItemsLoading";
    listView.onItemsLoaded = "onItemsLoaded";
    listView.onViewPortLoaded = "onViewPortLoaded";
    listView.onItemFocus = "onItemFocus";
    listView.onItemBlur = "onItemBlur";


    listView.prototype._setViewStateOld = listView.prototype._setViewState;
    listView.prototype._setViewState = function (state, detail) {
        this._setViewStateOld(state, detail);
        var eventObject;
        switch (state) {
            case this._LoadingState.viewPortLoaded:
                eventObject = document.createEvent("CustomEvent");
                eventObject.initCustomEvent(WinJS.UI.ListView.onViewPortLoaded, true, false, detail);
                this._element.dispatchEvent(eventObject);
                break;
            case this._LoadingState.itemsLoading:
                eventObject = document.createEvent("CustomEvent");
                eventObject.initCustomEvent(WinJS.UI.ListView.onItemsLoading, true, false, detail);
                this._element.dispatchEvent(eventObject);
                break;
            case this._LoadingState.complete:
                eventObject = document.createEvent("CustomEvent");
                eventObject.initCustomEvent(WinJS.UI.ListView.onItemsLoaded, true, false, detail);
                this._element.dispatchEvent(eventObject);
                break;
        }
    };

    listView.prototype._onFocusOld = listView.prototype._onFocus;
    listView.prototype._onFocus = function (event) {
        this._onFocusOld(event);
        var eventObject = document.createEvent("CustomEvent");
        eventObject.initCustomEvent(WinJS.UI.ListView.onItemFocus, true, false, event);
        this._element.dispatchEvent(eventObject);
    };

    listView.prototype._onBlurOld = listView.prototype._onBlur;
    listView.prototype._onBlur = function (event) {
        this._onBlurOld(event);
        var eventObject = document.createEvent("CustomEvent");
        eventObject.initCustomEvent(WinJS.UI.ListView.onItemBlur, true, false, event);
        this._element.dispatchEvent(eventObject);
    };

    listView.prototype.adjustExpanderItems = function () {
        var containers = new WinJS.Utilities.QueryCollection(this.element.querySelectorAll(".win-container"));
        var listView = this.element;
        if (containers.length > 0) {
            var top = 5;
            containers.forEach(function (container) {
                var listItem = container.querySelector(".win-item");
                if (listItem) {

                    var expanders = new WinJS.Utilities.QueryCollection(listItem.querySelectorAll(".win-expander"));
                    expanders.forEach(function (expander) {
                        expander.winControl.parentListView = listView;

                    }); //&& firstExpander == null
                    if (expanders[0]) {
                        expanders[0].winControl._adjustDimensions();
                    }
                }

                var h = Bixaps.Util.getListItemHeight(container);
                if (h > 0) {
                    container.style.top = top + "px";
                    container.style.height = h + "px";
                    top = top + h + 10;
                }

            });
            var h = Bixaps.Util.getListItemHeight(containers[0].parentNode);
            containers[0].parentNode.style.height = h + "px";
            var surface = this.element.querySelector(".win-surface");
            surface.style.height = h + "px";
            var backdrop = this.element.querySelector(".win-backdrop");
            backdrop.style.top = h + "px";
        }


    };

    WinJS.Class.mix(WinJS.UI.ListView,
        WinJS.Utilities.createEventProperties(

        WinJS.UI.ListView.onViewPortLoaded,
        WinJS.UI.ListView.onItemsLoading,
        WinJS.UI.ListView.onItemsLoaded,
        WinJS.UI.ListView.onItemFocus,
        WinJS.UI.ListView.onItemBlur

    ));

})();

(function () {

    "use strict";

    WinJS.Namespace.define("Bixaps.UI", {

        processAll: function () {

            Bixaps.UI.processExpanders();
        }
    });

})();


(function () {

    "use strict";

    WinJS.Namespace.define("Bixaps.UI.Animation", {

        slide: WinJS.Utilities.markSupportedForProcessing(function (elem, o) {
            var options = o || {};
            var t = {};
            var oldMargins = { top: elem.style.marginTop, left: elem.style.marginRight };
            var wrapper = document.createElement('div');
            if (options.wrapperStyle)
                wrapper.setAttribute('style', options.wrapperStyle);

            wrapper.style.overflow = 'hidden';
            elem.parentNode.replaceChild(wrapper, elem);
            wrapper.appendChild(elem);
            var mode = options.mode || 'show';
            elem.style.display = '';

            var ew = elem.offsetWidth;
            var eh = elem.offsetHeight;
            var dir = options.direction || 'down';
            if (dir === 'left' || dir === 'right') {
                if (elem.offsetWidth == 0)
                    elem.style.width = 'auto';
                t.property = 'margin-left';
                t.from = options.from || (dir == 'left') ? "0px" : (ew * -1) + "px";
                t.to = options.to || ((dir === 'left') ? (ew * -1) + "px" : '0px');
            } else {
                if (elem.offsetHeight == 0)
                    elem.style.height = 'auto';
                t.property = 'margin-top';
                t.from = options.from || (dir == 'up') ? "0px" : (eh * -1) + "px";
                t.to = options.to || ((dir === 'up') ? (eh * -1) + "px" : '0px');
            }

            t.delay = options.delay || 0;
            t.timing = options.timing || 'cubic-bezier(0.1, 0.9, 0.2, 1)';
            t.duration = options.duration || 400;

            var promise1 = WinJS.UI.executeTransition(elem, t).then(function () {
                var fragment = document.createDocumentFragment();
                while (wrapper.firstChild) {
                    fragment.appendChild(wrapper.firstChild);
                }
                wrapper.parentNode.replaceChild(fragment, wrapper);
                elem.style.marginTop = oldMargins.top;
                elem.style.marginLeft = oldMargins.left;
                elem.style.display = (mode === 'hide') ? 'none' : '';
            });

            return WinJS.Promise.join(promise1);
        })

    });

})();



/*********************************************
Expander control
*********************************************/
(function () {
    "use strict";

    WinJS.Namespace.define("Bixaps.UI",
        {
            Expander: WinJS.Class.define(function (element, options) {
                this.element = element || document.createElement("div");

                if (!this.element.parentNode) {
                    document.body.appendChild(this.element);
                }

                this._options = options || {};
                this.element.winControl = this;
                this._headerDataSource = {};
                this._contentDataSource = {};

                this._dataSource = {};


                this._parentListItem = null;
                this._parentListView = null;

                this._collapseImage = '';
                this._expandImage = '';

                this._create();

                WinJS.UI.setOptions(this, this._options);

                this._initLayout();

            },
                {
                    _icons: null,
                    _expanded: false,
                    _showPointer: true,
                    _disabled: false,
                    _freezeHeader: false,
                    _expandDirection: null,
                    _pointerPosition: null,
                    _create: function () {
                        this._contentTemplate = document.createElement("div");
                        this._headerPointer = document.createElement("div");
                        this._headerTemplateContainer = document.createElement("div");
                        this._headerTemplate = document.createElement("div");

                        this._headerContainer = document.createElement("div");
                        this._contentContainer = document.createElement("div");
                        this._controlContainer = document.createElement("div");
                        this._controlWrapper = document.createElement("div");
                    },
                    _initLayout: function () {

                        var element = this.element;
                        element.innerHTML = '';

                        this._headerContainer.className = '';
                        this._contentContainer.className = '';
                        this._headerPointer.className = '';
                        this._headerTemplateContainer.className = '';

                        WinJS.Utilities.addClass(element, "win-expander");
                        WinJS.Utilities.addClass(this._headerContainer, "win-expander-header");
                        WinJS.Utilities.addClass(this._contentContainer, "win-expander-content");
                        WinJS.Utilities.addClass(this._headerPointer, "win-expander-arrow");
                        WinJS.Utilities.addClass(this._headerTemplateContainer, "win-expander-headertext");


                        if (!this._expandDirection || this._expandDirection == '')
                            this._expandDirection = 'down';

                        if (!this._pointerPosition || this._pointerPosition == '')
                            this._pointerPosition = 'right';

                        if (this._expandDirection == "down" || this._expandDirection == "up") {
                            if (this._pointerPosition == "left") {
                                this._headerContainer.appendChild(this._headerPointer);
                                this._headerContainer.appendChild(this._headerTemplateContainer);
                            } else {
                                this._headerContainer.appendChild(this._headerTemplateContainer);
                                this._headerContainer.appendChild(this._headerPointer);
                            }

                            if (this._expandDirection == "up") {

                                element.appendChild(this._contentContainer);
                                element.appendChild(this._headerContainer);
                            } else {
                                element.appendChild(this._headerContainer);
                                element.appendChild(this._contentContainer);

                            }
                        } else if (this._expandDirection == 'right' || this._expandDirection == 'left') {

                            if (this._pointerPosition == "bottom") {

                                this._headerContainer.appendChild(this._headerTemplateContainer);
                                this._headerContainer.appendChild(this._headerPointer);
                            } else {
                                this._headerContainer.appendChild(this._headerPointer);
                                this._headerContainer.appendChild(this._headerTemplateContainer);
                            }

                            if (this._expandDirection == 'left') {

                                element.appendChild(this._contentContainer);
                                element.appendChild(this._headerContainer);

                            } else {
                                element.appendChild(this._headerContainer);
                                element.appendChild(this._contentContainer);
                            }

                        }


                        WinJS.Utilities.addClass(this._headerPointer, 'win-expander-arrow-' + this._pointerPosition);
                        WinJS.Utilities.addClass(element, "win-expander-" + this._expandDirection);
                        WinJS.Utilities.addClass(element, "collapsed");

                        this._updateArrows();
                        this._updateHeader();
                        this._updateContent();

                        this._hideContent();
                        element.setAttribute("aria-expanded", this._expanded);
                        element.setAttribute("aria-disabled", this._disabled);

                        var that = this;
                        this._headerContainer.onclick = function () {
                            if (!that._freezeHeader) {
                                that._expanded = !that._expanded;
                                that._refresh();
                            }
                        };

                        setTimeout(function () {
                            that._adjustDimensions();
                        }, 10);

                    },

                    _updateHeader: function () {
                        if (this._headerTemplate.winControl) {
                            this._headerTemplateContainer.innerHTML = '';
                            this._headerTemplate.winControl.render(this._headerDataSource, this._headerTemplateContainer);
                        }
                    },
                    _updateContent: function () {

                        if (this._contentTemplate.winControl) {
                            this._contentContainer.innerHTML = '';


                            if (this._contentDataSource instanceof Array) {
                                for (var index in this._contentDataSource) {
                                    this._contentTemplate.winControl.render(this._contentDataSource[index], this._contentContainer);
                                }

                            } else if (this._contentDataSource instanceof Function) {


                            } else {

                                this._contentTemplate.winControl.render(this._contentDataSource, this._contentContainer);
                            }
                        }

                    },
                    _updateArrows: function () {

                        switch (this._expandDirection) {
                            case 'up':

                                if (!this._icons) {
                                    this._icons = {
                                        expand: Bixaps.Util.Icons.ARROW_HEAD_UP, //up
                                        collapse: Bixaps.Util.Icons.ARROW_HEAD_LEFT //left
                                    };
                                }

                                break;
                            case 'left':
                                if (!this._icons) {
                                    this._icons = {
                                        expand: Bixaps.Util.Icons.ARROW_HEAD_LEFT, //left
                                        collapse: Bixaps.Util.Icons.ARROW_HEAD_DOWN //down
                                    };
                                }

                                break;
                            case 'right':
                                if (!this._icons) {
                                    this._icons = {
                                        expand: Bixaps.Util.Icons.ARROW_HEAD_RIGHT, //right
                                        collapse: Bixaps.Util.Icons.ARROW_HEAD_DOWN //down
                                    };
                                }
                                break;
                            default:
                                if (!this._icons) {
                                    this._icons = {
                                        expand: Bixaps.Util.Icons.ARROW_HEAD_DOWN, //down
                                        collapse: Bixaps.Util.Icons.ARROW_HEAD_RIGHT //right
                                    };
                                }
                                break;

                        }
                        try {


                            var expandImage = this._icons.expand || '';
                            var collapseImage = this._icons.collapse || '';

                            if (expandImage.indexOf("data:image") >= 0 || expandImage.indexOf(".png") >= 0
                                || expandImage.indexOf(".jpg") >= 0) {
                                var img = document.createElement('img');
                                img.src = expandImage;

                                expandImage = img;
                            }
                            if (collapseImage.indexOf("data:image") >= 0 || collapseImage.indexOf(".png") >= 0
                                || collapseImage.indexOf(".jpg") >= 0) {
                                var img = document.createElement('img');
                                img.src = collapseImage;
                                collapseImage = img;

                            }
                        } catch (e) {


                        }
                        this._expandImage = expandImage;
                        this._collapseImage = collapseImage;
                    },
                    //adjust dimensions 
                    _adjustDimensions: function () {

                        //bug fix for hidden parent container
                        this._contentContainer.style.display = '';
                        var parentNode, parentClass;
                        var node = this.element.parentNode;
                        if (node != document.body) {
                            while (node != null && node != 'undefined') {
                                var nstyle = document.defaultView.getComputedStyle(node, null);
                                if (nstyle) {
                                    var display = nstyle.getPropertyValue('display');
                                    if (display == 'none') {
                                        parentClass = node.className;
                                        node.style.display = '';
                                        node.className = '';
                                        parentNode = node;
                                        break;
                                    }
                                }
                                if (node == document.body)
                                    break;
                                node = node.parentNode;

                            }
                        }

                        //recalculate header and content dimensions
                        var cw = this._contentContainer.offsetWidth;
                        var ch = this._contentContainer.offsetHeight;

                        if (this._isUp || this._isDown) {
                            this._headerContainer.style.minWidth = cw + "px";
                            this._headerTemplateContainer.style.maxWidth = (cw - this._headerPointer.offsetWidth - 15) + "px";
                        } else {

                            var headerStyle = document.defaultView.getComputedStyle(this._headerContainer, null);
                            var maxWidth = "250px";
                            if (headerStyle) {
                                var mw = headerStyle.getPropertyValue('max-width');
                                if (mw)
                                    maxWidth = mw;
                            }
                            this._headerContainer.style.maxWidth = maxWidth;

                            cw = (this.element.offsetWidth - this._headerContainer.offsetWidth) - 15;
                            this._contentContainer.style.maxWidth = cw + "px";

                            var oh = this._contentContainer.offsetHeight;

                            this._headerContainer.style.minHeight = (ch > oh) ? ch : oh + "px";

                        }

                        this._contentContainer.style.display = 'none';

                        //refresh 
                        var oldExpand = this._expanded;
                        var that = this;
                        if (oldExpand) {
                            that._refresh(10);
                        }

                        //bugfix for hidden parent containers
                        if (parentNode) {
                            if (parentClass != '')
                                parentNode.className = parentClass;
                            else
                                parentNode.style.display = 'none';
                        }
                    }

                    //Refresh expander
                    , _refresh: function (duration) {

                        var content = this._contentContainer;
                        if (this._expanded) {
                            this._showContent();

                            if (this._isLeft || this._isRight) {

                                Bixaps.UI.Animation.slide(content, { direction: 'right', duration: duration, wrapperStyle: 'float:left;' });
                            } else {
                                Bixaps.UI.Animation.slide(content, { direction: 'down', duration: duration });
                            }

                        } else {
                            this._hideContent();

                            if (this._expandDirection == "left" || this._expandDirection == "right") {

                                Bixaps.UI.Animation.slide(content, { direction: 'left', mode: 'hide', wrapperStyle: 'float:left;' });

                            } else {
                                Bixaps.UI.Animation.slide(content, { direction: 'up', mode: 'hide' });

                            }
                        }

                        this.element.setAttribute("aria-expanded", this._expanded);

                        if (this._freezeHeader) {
                            if (!WinJS.Utilities.hasClass(this._headerContainer, 'freezeHeader')) {
                                WinJS.Utilities.addClass(this._headerContainer, 'freezeHeader');
                            }
                        } else {
                            if (WinJS.Utilities.hasClass(this._headerContainer, 'freezeHeader')) {
                                WinJS.Utilities.removeClass(this._headerContainer, 'freezeHeader');
                            }
                        }

                        this._headerPointer.style.display = this._showPointer ? '' : 'none';

                    },
                    _showContent: function () {

                        WinJS.Utilities.removeClass(this.element, "collapsed");
                        WinJS.Utilities.addClass(this.element, "expanded");
                        this._updateArrowImage(this._expandImage);

                        this.dispatchEvent("expand");


                    },
                    _hideContent: function () {
                        WinJS.Utilities.removeClass(this.element, "expanded");
                        WinJS.Utilities.addClass(this.element, "collapsed");

                        this._updateArrowImage(this._collapseImage);
                        this.dispatchEvent("collapse");
                    },
                    _updateArrowImage: function (img) {
                        if (img instanceof HTMLImageElement) {
                            this._headerPointer.innerHTML = '';
                            this._headerPointer.appendChild(img);
                        } else {
                            this._headerPointer.innerHTML = window.toStaticHTML(img);
                        }
                    },
                    _adjustListView: function () {

                        var parent = this._parentListItem;

                        if (!Bixaps.Util.IsNull(parent)) {

                            var top = Bixaps.Util.getTop(parent);

                            try {
                                var h = WinJS.Utilities.getContentHeight(parent);

                                if (h > 0) {

                                    parent.style.height = h + "px";
                                    var nextTop = top + h + 5;
                                    var next = parent.nextSibling;
                                    while (!Bixaps.Util.IsNull(next)) {

                                        if (next.nodeType == 1) {
                                            next.style.top = nextTop + "px";
                                            top = Bixaps.Util.getTop(next);
                                            h = WinJS.Utilities.getContentHeight(next);
                                            nextTop = top + h + 5;
                                        }
                                        next = next.nextSibling;
                                    }


                                }
                            } catch (e) {
                            }


                        }
                    },
                    _isLeft: {
                        get: function () {
                            return (this._expandDirection == 'left');
                        }
                    },
                    _isRight: {
                        get: function () {
                            return (this._expandDirection == 'right');
                        }
                    },
                    _isDown: {
                        get: function () {
                            return (this._expandDirection == 'down');
                        }
                    },
                    _isUp: {
                        get: function () {
                            return (this._expandDirection == 'up');
                        }
                    },
                    //public methods
                    expanded: {
                        get: function () {
                            return this._expanded;
                        },
                        set: function (value) {
                            this._expanded = value;
                        }
                    },
                    expand: function () {
                        this._expanded = true;
                        this._refresh();
                    },
                    collapse: function () {
                        this._expanded = false;
                        this._refresh();
                    },
                    headerTemplate: {
                        set: function (value) {
                            if (value) {

                                this._headerTemplate = value;
                            }
                        }
                    }
                    ,
                    contentTemplate: {
                        set: function (value) {
                            if (value) {
                                this._contentTemplate = value;
                            }
                        }
                    },
                    dataSource:
                        {
                            set: function (data) {
                                if (data instanceof Array) {
                                    if (data[0]) {
                                        this._headerDataSource = data[0];
                                    }
                                    if (data[1]) {
                                        this._contentDataSource = data[1];
                                    }
                                }
                                else
                                    if (data instanceof Object) {

                                        if (data.header) {
                                            this._headerDataSource = data.header;
                                        }
                                        if (data.content) {
                                            this._headerDataSource = data.content;
                                        }
                                    }
                            }
                        },
                    headerDataSource: {
                        set: function (data) {
                            this._headerDataSource = data;
                        }
                    },
                    contentDataSource: {
                        set: function (data) {
                            this._contentDataSource = data;
                        }
                    },
                    expandDirection: {
                        get: function () {
                            return this._expandDirection;
                        },
                        set: function (dir) {

                            this._expandDirection = dir;
                        }
                    },
                    pointerPosition: {
                        get: function () {
                            return this._pointerPosition;
                        },
                        set: function (val) {

                            this._pointerPosition = val;
                        }
                    },
                    freezeHeader: {
                        get: function () {
                            return this._freezeHeader;
                        },
                        set: function (val) {

                            this._freezeHeader = val;
                        }
                    },
                    showArrow: {
                        get: function () {
                            return this._showPointer;
                        },
                        set: function (val) {

                            this._showPointer = val;
                        }
                    },
                    icons: {
                        set: function (val) {
                            this._icons = val;
                            this._updateArrows();
                        }
                    },
                    disabled: {
                        get: function () {
                            return this._disabled;
                        },
                        set: function (val) {

                            this._disabled = val;
                        }
                    },
                    forceLayout: function () {
                        this._expandImage = '';
                        this._collapseImage = '';
                        this._initLayout();
                    },
                    parentListItem: {
                        set: function (item) {
                            this._parentListItem = item;
                        }
                    },
                    parentListView: {
                        set: function (view) {
                            this._parentListView = view;
                        }
                    }

                }
            )
        });

    WinJS.Class.mix(Bixaps.UI.Expander, WinJS.Utilities.createEventProperties(
           "expand"
          , "collapse"
      ), WinJS.UI.DOMEventMixin);
})();



/*********************************************
NumericBox control
*********************************************/


(function () {
    "use strict";

    WinJS.Namespace.define("Bixaps.UI",
        {
            NumericBox: WinJS.Class.define(function (element, options) {

                element = element || document.createElement("span");
                this._options = options || {};
                element.winControl = this;
                WinJS.UI.setOptions(this, options);
                this._init(element);

            }, {
                _min: null,
                _max: null,
                _step: 1,
                _placeHolder: '',
                _format: null,
                _value: null,
                _stepDirection: 1,
                _decimalPlaces: 2,
                _hasFocus: false,
                _valueChanged: false,
                _mouseTimer: null,
                _icons: null,
                _iconsCssClass: null,
                _init: function (element) {
                    this._setElement(element);
                    //this._refresh();
                    this._displayFormat(true);
                },
                _setElement: function (element) {

                    if (element instanceof HTMLInputElement) {
                        this._domElement = document.createElement("span");
                        this._inputElement = element;
                        this._domElement.winControl = this;
                        delete element.winControl;
                    } else {
                        this._domElement = element;
                        WinJS.Utilities.empty(this._domElement);
                        this._inputElement = document.createElement("input");
                    }
                    this._inputElement.setAttribute("type", "number");

                    this._upElement = document.createElement("a");
                    this._downElement = document.createElement("a");

                    if (!this._domElement) { return; }

                    if (this._inputElement.parentNode != null) {
                        this._inputElement.parentNode.insertBefore(this._domElement, this._inputElement);
                    }

                    this._upButton = document.createElement("span");
                    this._downButton = document.createElement("span");

                    this._refreshIcons();

                    WinJS.Utilities.addClass(this._domElement, "win-numericbox");
                    WinJS.Utilities.addClass(this._inputElement, "win-numericbox-input");
                    WinJS.Utilities.addClass(this._upElement, "win-numericbox-button win-numericbox-up");
                    WinJS.Utilities.addClass(this._downElement, "win-numericbox-button win-numericbox-down");
                    WinJS.Utilities.addClass(this._upButton, "win-numericbox-up-icon");
                    WinJS.Utilities.addClass(this._downButton, "win-numericbox-down-icon");

                    this._upElement.appendChild(this._upButton);
                    this._downElement.appendChild(this._downButton);

                    this._domElement.appendChild(this._inputElement);
                    this._domElement.appendChild(this._downElement);
                    this._domElement.appendChild(this._upElement);

                    var that = this;

                    var mouseTimer;
                    this._upElement.addEventListener("mousedown", function (e) {
                        that._updateValue();
                        mouseTimer = setInterval(that.stepUp(), 100);

                    });

                    this._upElement.addEventListener("mouseup", function (e) {
                        clearInterval(mouseTimer);
                    });

                    this._downElement.addEventListener("mousedown", function () {
                        that._updateValue();
                        mouseTimer = setInterval(that.stepDown(), 100);
                    });

                    this._downElement.addEventListener("mouseup", function () {
                        clearInterval(mouseTimer);
                    });

                    this._inputElement.addEventListener("focus", function (e) {
                        that._onFocus(e);
                    });
                    this._inputElement.addEventListener("blur", function (e) {
                        that._onBlur(e);
                    });

                    this._inputElement.addEventListener("keydown", function (e) {
                        that._inputKeyDown(e);

                    });

                    this._inputElement.addEventListener("mousewheel", function (e) {
                        that._inputMouseWheel(e);
                    });

                    if (this._min != null) {
                        this._value = this._min;
                        //this._inputElement.value = this._min;
                    }

                    setTimeout(function () {
                        that._adjustDimensions();
                    }, 10);



                },
                _adjustDimensions: function () {

                    var h = WinJS.Utilities.getContentHeight(this._inputElement);

                    var style = document.defaultView.getComputedStyle(this._inputElement);

                    var t = eval(h);
                    if (style.marginTop) {
                        var m = style.marginTop.replace("px", "");
                        t += eval(m);
                    }
                    if (style.borderTop) {
                        var b = style.borderTop.replace("px", "");
                        t += eval(b);
                    }
                    this._upElement.style.lineHeight = h + "px";
                    this._downElement.style.lineHeight = h + "px";
                    this._upElement.style.height = t + "px";
                    this._downElement.style.height = t + "px";
                },
                _updateDisplay: function (reset) {
                    this._adjustValue();
                    this._refresh();
                    this._displayFormat(reset);
                },
                _swapValue: function () {
                    this._valueChanged = false;

                    this._inputElement.value = this._value;
                    this._inputElement.defaultValue = this._value;
                    this._inputElement.setAttribute('placeholder', '');
                },
                _displayFormat: function (reset) {

                    if (!this._inputElement)
                        return;
                    var val = this._value;
                    if (reset) {
                        this._inputElement.value = '';
                    }
                    this._inputElement.defaultValue = val;
                    if (!isNaN(val)) {
                        val = this._adjustDecimals(val);
                        var formatStr = val;

                        if (this._format != null && this._format.length > 0) {

                            switch (this._format.charAt(0).toLowerCase()) {
                                case 'c':
                                    formatStr = '$' + val;
                                    break;
                                case 'p':
                                    formatStr = val + '%';
                                    break;
                                case 'e':
                                    formatStr = val + 'e+0';
                                    break;
                            }
                        }
                        this._inputElement.setAttribute("placeholder", formatStr);
                    }
                },
                _refresh: function () {
                    if (this._inputElement != null) {
                        this._inputElement.value = this._value;

                    }
                },
                _updateValue: function () {

                    if (this._valueChanged) {
                        if (!isNaN(this._inputElement.value)) {
                            if (this._inputElement.defaultValue != this._inputElement.value) {
                                var val = this._inputElement.value;
                                val = this._adjustDecimals(val);
                                this._value = val;
                                this._checkValue();
                                this._valueChanged = false;

                            }
                        }
                    }
                },
                _checkValue: function () {
                    var origValue = this._value;
                    var val = origValue;
                    if (val != null) {
                        if (this._min != null) {
                            if (val < this._min)
                                val = this._min;
                        }
                        if (this._max != null && val > this._max) {
                            val = this._max;
                        }
                        //if (val != origValue) {
                        this._value = val;
                        //}
                    }
                },
                _adjustDecimals: function (val) {
                    if (val && !isNaN(val)) {
                        val = eval(val);
                        var checkValDecimal = val % 1 != 0;
                        var checkStepDecimal = this._step % 1 != 0;
                        if (checkValDecimal || checkStepDecimal) {
                            val = val.toFixed(this._decimalPlaces || 0);
                        }
                    }
                    return val;
                },
                _adjustValue: function () {
                    var val = this._value || 0;
                    if (val != null) {
                        val = eval(val) + (this._stepDirection * this._step);
                        val = this._adjustDecimals(val);
                        this._value = val;
                    }
                    this._checkValue();
                },
                _inputKeyDown: function (e) {
                    var keys = Bixaps.Util.Keys;
                    var code = e.keyCode;
                    if (code == keys.UP) {
                        this._stepUp(false);
                    } else if (code == keys.DOWN) {
                        this._stepDown(false);
                    }

                    if ((code >= 47 && code <= 57) || code == 190 || code == 8 || code == 46) {
                        this._valueChanged = true;
                    }
                    return true;
                },
                _inputMouseWheel: function (e) {
                    if (!this._hasFocus) {
                        console.log('focus');
                        this._inputElement.focus();
                        this._hasFocus = true;
                    }
                    if (e.wheelDelta > 0) {

                        this._stepUp(false);

                    }
                    else {
                        this._stepDown(false);

                    }

                },
                _onFocus: function (e) {
                    this._valueChanged = false;
                    this._hasFocus = true;
                    this._refresh();
                },
                _onBlur: function (e) {
                    this._hasFocus = false;
                    this._updateValue();
                    this._displayFormat(true);

                },
                _stepUp: function (reset) {
                    this._stepDirection = 1;
                    this._updateDisplay(reset);
                    this._onStep();
                    this._onStepDown();
                },
                _stepDown: function (reset) {
                    this._stepDirection = -1;
                    this._updateDisplay(reset);
                    this._onStep();
                    this._onStepUp();
                },
                _onStep: function () {
                    var eventObject = document.createEvent("CustomEvent");
                    eventObject.initCustomEvent("step", false, false, { "control": this });
                    this._domElement.dispatchEvent(eventObject);
                },
                _onStepUp: function () {
                    var eventObject = document.createEvent("CustomEvent");
                    eventObject.initCustomEvent("stepup", false, false, { "control": this });
                    this._domElement.dispatchEvent(eventObject);
                },
                _onStepDown: function () {
                    var eventObject = document.createEvent("CustomEvent");
                    eventObject.initCustomEvent("stepdown", false, false, { "control": this });
                    this._domElement.dispatchEvent(eventObject);
                },
                _refreshIcons: function () {

                    if (!this.iconsCssClass) {
                        if (!this._icons) {
                            this._icons = {
                                up: Bixaps.Util.Icons.ARROW_HEAD_UP,
                                down: Bixaps.Util.Icons.ARROW_HEAD_DOWN
                            };
                        }

                        if (this._icons.up && this._icons.up.indexOf('data:image') >= 0
                            || this._icons.up.indexOf('.jpg')
                            || this._icons.up.indexOf('.png')) {
                            var img = document.createElement('img');
                            img.src = this._icons.up;

                            this._upButton.innerHTML = '';
                            this._upButton.appendChild(img);
                        } else {
                            this._upButton.innerHTML = window.toStaticHTML(this._icons.up);
                        }

                        if (this._icons.up && this._icons.down.indexOf('data:image') >= 0
                          || this._icons.down.indexOf('.jpg')
                          || this._icons.down.indexOf('.png')) {
                            var img = document.createElement('img');
                            img.src = this._icons.down;

                            this._downButton.innerHTML = '';
                            this._downButton.appendChild(img);
                        } else {
                            this._downButton.innerHTML = window.toStaticHTML(this._icons.down);

                        }

                    } else {

                        WinJS.Utilities.addClass(this._upButton, this._iconsCssClass.up);
                        WinJS.Utilities.addClass(this._upButton, this._iconsCssClass.down);
                    }
                },
                min: {
                    get: function () {
                        return this._min;
                    },
                    set: function (value) {
                        this._min = value;
                    }
                },
                max: {
                    get: function () {
                        return this._max;
                    },
                    set: function (value) {
                        this._max = value;
                    }
                },
                step: {
                    get: function () {
                        return this._step;
                    },
                    set: function (value) {
                        this._step = value;
                    }
                },
                format: {
                    get: function () {
                        return this._format;
                    },
                    set: function (value) {
                        this._format = value;
                    }
                },
                value: {
                    get: function () {
                        return this._value;
                    },
                    set: function (value) {
                        value = this._adjustDecimals(value);
                        this._value = value;
                        this._refresh();
                    }
                },
                decimalPlaces: {
                    get: function () {
                        return this._decimalPlaces;
                    },
                    set: function (value) {
                        this._decimalPlaces = value;
                    }
                },
                icons: {
                    get: function () {
                        return this._icons;
                    },
                    set: function (val) {
                        this._icons = val;
                        this._refreshIcons();
                    }
                },
                iconsCssClass: {
                    get: function () {
                        return this._iconCssClass;
                    },
                    set: function (val) {
                        this._iconCssClass = val;
                        this._refreshIcons();

                    }
                },
                stepUp: function () {

                    this._stepUp(true);
                },
                stepDown: function () {


                    this._stepDown(true);
                }
            })
        });

    WinJS.Class.mix(Bixaps.UI.NumericBox,
       WinJS.Utilities.createEventProperties(
        "step",
        "stepup",
        "stepdown"
   ));

})();